package chat.model;
import java.io.*;
import java.util.*;

/**  'ChatListener.java'  created by: Team N3 for Swinburne Uni HET715s2/Dr. Recep Ulusoy, 2/10/2012 v0.0 (final)
* 	<br/>
*   A simple Class program set that accompanies the Chat Client program, called by ClientConnection.  Its main function is to  
*   process the flags and I/O stream returning from the Chat Server, (at the Client end).
*	(NOTE:  Diagnostic feedback is visible if a Command Prompt window is opened).
*   
* @see Observer, ObserverChat, ObserverList
* @author Tung Nguyen, Trung V Hoang, Rob Bernard, Justin Semmel
* @since October 2012
*
*
*/
public class ChatListener implements Runnable, ObservableChatListener  {
	private BufferedReader input;
	private boolean stop;
	private ArrayList <ObserverChatListener> observerList;
	private String message;
	
	/**
	*   Constructor for Listener
	*   (setup variables and methods)
	*/
	public ChatListener()
	{
		stop = true;	
		observerList = new ArrayList<ObserverChatListener>();
	}
	
	/** initialize the listening thread
	 * @param inStream
	 */
	public ChatListener(InputStream inStream)
	{
		stop = false;				// Prepare flag and Observer array
		observerList = new ArrayList<ObserverChatListener>();
		
		try  {					// Create Error Handler for Listen I/O
			input = new BufferedReader(new InputStreamReader(inStream) );
		}
		catch(Exception ex)// Error-Handler with Diag print to CLI screen
		{
			//there is an error here
			System.err.println("Error when create chat listening thread: " + ex.toString());
		}
	}
	
	/** Create the input stream to receive message from the server
	 * @param inStream
	 */
	public void createInputPipe(InputStream inStream)
	{
		stop = false;
		
		try
		{
			input = new BufferedReader(new InputStreamReader(inStream) );
		}
		catch(Exception ex)
		{
			//there is an error here
			System.err.println("Error when create chat listening thread: " + ex.toString());
		}		
	}
	

	/**
	*  setStop and isStopped methods (simple flag management actions)
	*/
	public void setStop(boolean value)
	{
		stop = value;
	}
	
	public boolean isStopped()  {				// * Checks value of 'Stop' flag (to TRUE)
		return stop == true;				// Comparess the new flag value (TRUE / logic1)
	}						//    and returns status of the decision

	/**
	*   update Observer and end-detect method
	*/	
	public void run()
	{
		// Create Error Handler for Listen I/O
		try
		{
			while ( !isStopped() )	// If not stopped, check for end & notify
			{
				message = input.readLine();
				if (!isStopped())
				{
					if (message.contains(ApplicationConstant.QUIT_STRING))
					{
						message = "Connection is closed";
						setStop(true);	// yes, ended, so signal this state
					}
					//notify the observer
					notifyObserverChatListener_ReceivingMessage();	//Update the Observer, whatever
				}
			}
		}
		catch(Exception ex) // Error-Handler with Diag print to CLI screen
		{
			System.err.println("Error when reading input: " + ex.toString());
		}
	}
	
	/**
	*   Observer Management
	*   notify the observer that we have new message, please update the message log
	*/		
	public void notifyObserverChatListener_ReceivingMessage()
	{
		for (ObserverChatListener observer: observerList)
		{
			System.out.println("Chat client receives a message " + message);
			// Observer update & Diag print to CLI screen
			observer.updateResponse(message);
		}
	}
	
	/**
	* add observer to observerList
	*/
	public void addObserverChatListener(ObserverChatListener observer)
	{
		observerList.add(observer);
	}
}